import json
import logging

from utils.AssertUtil import AssertUtil
from utils.YamlUtil import YamlUtil
from utils.log_util import logger


class ExtractUtil:
    def __init__(self):
        self.jsonpath_util = AssertUtil() # 引入自己封装的断言工具类
        self.yaml_util = YamlUtil() # 引入yaml文件操作工具类

    def extract_data(self, res, extract):
        """
        将接口的响应结果提取出来存入到yaml中
        :param res: res.json
        :param extract: eg:$.token
        :return:
        """
        if extract:
            for key,expression in extract.items():
                try:
                    value = self.jsonpath_util.extract_by_jsonpath(res,expression)
                    logger.info(f"====================从文件中获取到的extract的内容为：{value}")
                    print(f"====================从文件中获取到的extract的内容为：{value}")
                    # 写入value
                    self.yaml_util.write_extra_yaml({key:value})
                except Exception as e:
                    logger.error(f"变量{key}写入extract.yaml失败，请检查，error={e}")

    def get_extract_value(self, key):
        """从extract.yaml中获取内容"""
        try:
            data = self.yaml_util.read_extract_yaml()
            return data[key]
        except Exception as e:
            logger.error(f"从extract.yaml文件中根据{key}获取不到内容，error={e}")

    def extract_url(self,url):
        """
            检查 url是否包含 ${...}这样的占位符。
            如果有，则调用 process_data方法处理并替换占位符
            如果没有，则直接返回原始 url
        """
        if "${" in url and "}" in url:
            return self.process_data(url)
        return url

    def process_data(self,data):
        """处理函数"""
        for i in range(data.count("${")):
            if "${" in data and "{" in data:
                start_index = data.index('$') # 找到 $的位置
                end_index = data.index('}') # 找到 }的位置
                # 获取函数中的方法
                func_full_name = data[start_index:end_index+1] # 此处的end_index+1是因为切片的尾部不是闭区间
                # 获取函数名
                func_name = data[start_index+2:data.index('(')] # eg: /orders/${get_extract_value(order_id)}/  get_extract_value
                # 获取函数中的参数
                func_params = data[data.index('(')+1:data.index(')')] # eg: /orders/${get_extract_value(order_id)}/  order_id
                # 先进行getattr获取对象
                extract_data = getattr(self,func_name,None)
                if extract_data is not None:
                    # 1.拆分参数
                    if func_params: # 如果func_name不是空字符串
                        param_list = func_params.split(",") # 按逗号分割成列表
                    else:
                        param_list = []

                    # 2.如果有数字，尝试将参数转换为整数
                    processed_params = []
                    for param in param_list:
                        if param.isdigit(): # 检查是否是纯数字字符串（如"123"）
                            processed_params.append(int(param))
                        else:
                            processed_params.append(param)
                    # 3.调用方法并传入处理后的参数
                    result = extract_data(*processed_params) # 相当于extract_data(params1,params2,...)
                    extract_data = result # 更新 extract_data 为调用后的返回值
                data = data.replace(func_full_name, str(extract_data))
        return data

    def extract_case(self, case_info):
        str_case_info = json.dumps(case_info) # 将 case_info 转为 JSON 字符串（确保统一处理）
        data = self.process_data(str_case_info) # 调用 process_data 方法解析字符串中的动态占位符（如 ${xxx}）
        return json.loads(data) # 将处理后的字符串重新转回 JSON 结构（字典/列表等）